<?php
/**
 * appRain v 0.1.x
 *
 * LICENSE
 *
 * This source file is subject to the MIT license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.opensource.org/licenses/mit-license.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@apprain.com so we can send you a copy immediately.
 *
 * @copyright  Copyright (c) 2010 appRain, Inc. (http://www.apprain.com)
 * @license    http://www.opensource.org/licenses/mit-license.php MIT license
 *
 * HELP
 * 
 * Official Website 
 * http://www.apprain.com/
 *
 * Download Link
 * http://www.apprain.com/download
 *
 * Documents Link
 * http ://www.apprain.com/documents
 */

/**
 * Admin Controller
 */
class developerController extends appRain_Base_Core 
{
    public $name = 'Developer';
    
    
    /**
     * Admin index
     *
     * @parameter admin_flag string
     *
     * @return null
     */
    public function indexAction( $admin_flag = 'introduction')
    {
        $this->redirect('/admin/' . app::__def()->sysConfig('ADMIN_REDIRECTION'));
        exit;
    }

    /*
     * Developer file manager
     *
     * @parameter path string
     * @parameter file2edit string
     */
    public function editorAction( $path = "", $file2edit = NULL)
    {
        $this->setAdminTab('developer');

        $this->page_title = "Developer Page editor";
        $message = false;

        $path = isset( $path ) && ($path != "") ? $path : base64_encode( "" );

        $pathbase = App::load("Helper/Config")->get('basedir') . base64_decode( $path) ;

        # Directory listing
        $dir_listing = App::load("Helper/Utility")->getDirLising($pathbase);
        $this->set("base_path",base64_decode($path));
        $this->set("dir_listing",$dir_listing);

        
        if( isset( $file2edit ) )
        {
            $filepath = App::load("Helper/Config")->get('basedir') . base64_decode($path) . '/' . base64_decode( $file2edit );

            if( !empty( $this->data ) && (is_writable($filepath)))
            {
                 App::Load("Helper/Utility")->savefilecontent( $filepath, $this->data['Editor']['content']);
            }

            if(!is_writable($filepath)) $message = $this->__("File is not writable!");

            $file2editcontent = App::Load("Helper/Utility")->fatchfilecontent($filepath);
            $this->set('file2editcontent',$file2editcontent);
            $this->set("filepath",$filepath);
        }

        $this->set("message",$message);
    }
    
    /**
     * View phpinfo()
     *
     * @return null
     */
    public function showmyphpinfoAction()
    {
       $this->setAdminTab('developer');
        $this->page_title = "PHP info";
    }


    /**
     * Manage appRain theme
     *
     * @parameter theme2install string
     * @return null
     */
    public function themeAction( $theme2install = NULL)
    {
        // Sec Admin TAB
        $this->setAdminTab('developer');

        if( isset($theme2install))
        {
            $new_theme = base64_decode($theme2install);
            $current_user_id = $this->getUserStatusId();

            $row = $this->Config->find("fkey=$current_user_id AND soption='theme'");

            if( !empty( $row ))
            {
                $result = $this->Config->save(
                                array( 
                                        "Config" => array("svalue" =>$new_theme)),
                                        "soption='theme' AND fkey= $current_user_id" 
                                );
            }
            $this->redirect("/developer/theme");
            exit;
        }
        
        /*
         * Fetch themes
         */
        $theme_info = App::Load('Helper/Utility')->getDirLising(VIEW_PATH);
        $themes = Array();
        $themes_default = Array();
        foreach( $theme_info['dir'] as $val )
        {
            $path = VIEW_PATH . DS . $val['name'];

            if( file_exists("{$path}/definition/info.xml"))
            {
                $info =         App::Load("Helper/Utility")->fatchfilecontent("{$path}/definition/info.xml");
                $name =         App::Load("Helper/Utility")->get_value_by_tag_name($info,"<name>","</name>");
                $desc =         App::Load("Helper/Utility")->get_value_by_tag_name($info,"<description>","</description>");
                $author =       App::Load("Helper/Utility")->get_value_by_tag_name($info,"<author>","</author>");
                $author_uri =   App::Load("Helper/Utility")->get_value_by_tag_name($info,"<author_uri>","</author_uri>");

                $basepath = $path;

                $image = App::Load("Helper/Utility")->get_value_by_tag_name($info,"<image>","</image>");

                if( $name != "" && $desc != "" && $image != "" )
                {
                    $tmp = array
                                    (
                                        "name" => $val['name'],
                                        "title" => $name,
                                        "description"=> $desc, 
                                        "image" => $image,
                                        "basepath"=>$basepath,
                                        'author' => $author,
                                        'author_uri' => $author_uri
                                    );

                    if( $this->theme == $val['name'] )
                    {
                         $themes_default =  $tmp;
                    }
                    else
                    {
                        $themes[] =  $tmp;
                    }
                }
            }
        }
        $this->set("themes",$themes);
        $this->set("themes_default",$themes_default);
    }
    
    /**
     * Import/Export Database
     * Output format is XML
     *
     * @return null
     */
    public function imexportAction( $action = null, $dta = NULL)
    {
        // Set tab and layout
        $this->setAdminTab('developer');

        $this->page_title = "Backup Database";
       // $this->load_plugins(array('dbimexport'));
        
        if( $action == 'delete')
        {
            unlink(DATA . DS . "database/" . base64_decode($dta));
            $this->redirect('/developer/imexport/');
            exit;
        }

        $import_err = "";
        $backup_err = "";
        $restore_err = "";
        if( !empty( $this->data ))
        {
            if( isset($this->data['ImExport']['export']))
            {
                App::Load("Module/Dbimexport")->download = true;
                App::Load("Module/Dbimexport")->file_name = date("Y-m-d_H-i-s");
                App::Load("Module/Dbimexport")->export();
            }
            else if ( isset($this->data['ImExport']['import']) )
            {
                if(  $this->data['ImExport']['filename']['name'] == "")
                {
                    $import_err = "Select a valid database file";
                }
                else
                {
                   $raw_file = App::Load("Helper/Utility")->upload( $this->data['ImExport']['filename'], TEMP . DS );
                   App::Load("Module/Dbimexport")->import_path = TEMP . DS . $raw_file['file_name']; 

                   App::Load("Module/Dbimexport")->import();
                   $import_err = "Database Imported successfully";
                   @unlink(App::Load("Module/Dbimexport")->import_path);
                }
            }
            else if ( isset($this->data['ImExport']['backup']))
            {
                App::Load("Module/Dbimexport")->file_name = $this->data['ImExport']['filename'];
                App::Load("Module/Dbimexport")->download_path = DATA . DS . "database";
                App::Load("Module/Dbimexport")->export();
                $backup_err = "Backup has creaded successfully.";
            }
            else if ( isset($this->data['ImExport']['restore']))
            {
                if( $this->data['ImExport']['file_name'] == "")
                {
                    $restore_err = "No Database file selected";
                }
                else
                {
                    App::Load("Module/Dbimexport")->import_path = DATA . DS . "/database/{$this->data['ImExport']['file_name']}"; 
                    App::Load("Module/Dbimexport")->import();
                    $restore_err = "Database restorded successfully to {$this->data['ImExport']['file_name']}";
                }
            }
        }

        $database_files =App::load("Helper/Utility")->getDirLising(DATA . DS . "database");

        $this->set("database_files", $database_files);
        $this->set("restore_err", $restore_err);
        $this->set("import_err", $import_err);
        $this->set("backup_err", $backup_err);
    }

    public function sys_configAction()
    { 
        // Check authonitcation
        $this->setAdminTab('developer');

        $this->page_title = 'System Configuration';
        $message = "";
        $file_path = CONFIG_PATH . DS . "config.xml";
        $definition = array();
        $dom = new DOMDocument();
        $dom->load($file_path);

        if( isset($this->post['Button']['button_save']))
        {
            if( is_writeable($file_path))
            {
                $this->data['sconfig'] = isset($this->data['sconfig']) ? $this->data['sconfig'] : array();
                $options = $dom->getElementsByTagName('option');
                foreach( $options as $option )
                {
                    $name = $option->getAttribute('name');
                    $option->getElementsByTagName('value')->item(0)->nodeValue = '';

                    if( in_array($name, array_keys($this->data['sconfig'])))
                    {
                        $cdataNode = $dom->createCDATASection($this->data['sconfig'][$name]);
                        $option->getElementsByTagName('flag')->item(0)->nodeValue = 0;
                        
                    }
                    else 
                    {
                        $cdataNode = $dom->createCDATASection($option->getElementsByTagName('default')->item(0)->nodeValue);
                        $option->getElementsByTagName('flag')->item(0)->nodeValue = 1;
                    }
                
                    $option->getElementsByTagName('value')->item(0)->appendChild( $cdataNode );
                    
                }

                $dom->save ( $file_path );
                $this->redirect("/developer/sys-config",'javascript');

            } 
            else
            {
               $message = "Your configuration file is not writeable($file_path).";
            }
        }

        $this->set('message',$message);
        $this->set('sysconf',$dom);
    } 

    public function uri_managerAction()
    { 

    }

    public function debuggerAction()
    { 
        $this->layout = 'admin';
        $this->admin_tab = 'developer';
        $this->page_title = 'System Configuration';
    } 

    public function mvcmanagerAction( $action = "")
    {
    	$this->setAdminTab('developer');

        if( $action != 'create')
        {
            $mvcdata = $this->get_mvc_data($action);
            $this->set('mvcdata', $mvcdata);
        }

        $this->set('action',$action);
    }


    private function get_mvc_data( $model = "")
    {
        $models = App::Load('Helper/Utility')->getDirLising(MODEL_PATH);

        $_mvc_data = Array();
        foreach( $models['file'] as $val )
        {
			
            $name = App::Load("Helper/Utility")->getName($val['name']);

            if( ($model == "") || $name == $model)
            {
                $_mvc_data[$name]['model']['version']    = App::Load("Model/{$name}")->version;
                $_mvc_data[$name]['model']['db_table']   = App::Load("Model/{$name}")->db_table;
                $_mvc_data[$name]['model']['exists']     = true;   
                $_mvc_data[$name]['model']['path']       = "/development/models/" ; 
                $_mvc_data[$name]['model']['name']       = App::Load("Model/{$name}")->name;
                $_mvc_data[$name]['model']['insteller']['exists']  = ( file_exists(MODEL_PATH . DS . 'installer' . DS . $val['name'] )) ? true : false;

                if( file_exists(CONTROLLER_PATH . DS . $val['name'] ))
                {
                    $_mvc_data[$name]['controller']['path']     = "/development/controllers/" ;
                    $_mvc_data[$name]['controller']['exists']   = true;
                    $_mvc_data[$name]['controller']['name']     = $name;

                }
                else 
                {
                    $_mvc_data[$name]['controller']['exists']   = false;
                }

                if( file_exists(VIEW_PATH . DS . $this->theme . DS . $name))
                {
                    $views = App::Load('Helper/Utility')->getDirLising( VIEW_PATH . DS . $this->theme . DS . $name);
                    $_mvc_data[$name]['view']['path'] = VIEW_PATH . DS . $this->theme . DS . $name;
                    $_mvc_data[$name]['view']['exists'] = true;

                    foreach( $views['file'] as $vnode )
                    {   
                        $_mvc_data[$name]['view']['files'][] = array(
                                                                        'name' => App::Load("Helper/Utility")->setFileName($vnode['name'])->getName(),
                                                                        'url' => App::Load('Helper/Config')->baseurl( DS . $name . DS . str_replace('_','-',App::Load("Helper/Utility")->setFileName($vnode['name'])->getName())),
                                                                        'path' => "/development/view/" . $this->theme . DS . $name ,
                                                                        'file_name' => $vnode['name']
                                                                    );
                    }
                }
                else 
                {
                    $_mvc_data[$name]['view']['exists'] = false;
                }
            }
        }

        // Return GROSS
        return $_mvc_data;
    }

    public function webserviceAction($className = NULL,$service = false)
    {
        
    	$this->layout = "blank";
		
        $niddles = split("[_]",$className);
        $className = "Development_Helper_Api_{$niddles[count($niddles)-1]}";
        
	    if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST') 
	    {
	    	App::Load("Module/Webservice")->setClassName($className)
			  							  ->loadServer();
		}
		else 
		{
		    

			if ($service) 
            {
				echo App::Load("Module/Webservice")->setClassName($className)
				  							  	   ->setServiceName("appRain")
				  							  	   ->showWSDL();
			}
			else 
            {
				echo App::Load("Module/Webservice")->setClassName($className)
				  								   ->setServiceName("appRain")
				  								   ->showWSDLURI();
			}
		}
    }

    public function updateAction($state=NULL)
    {  
        $this->setAdminTab('developer');

		$this->addons = array('validation','ajaxsubmit','versionupdater');

        $newVersion = App::Load("Module/Updatemanager")->getNewVersion();

		if(!empty($this->data))
		{
		  	try 
            {	
            	switch($state)
            	{
            		case  "start"	:
            							
                                        App::Load("Module/Updatemanager")->checkappupdate($this->data['Update']['licensekey']);
            							break;
            		default			:
                						App::Load("Module/Updatemanager")->checkappupdate($this->data['Update']['licensekey']);
                						echo $this->__("Redirect|" . $this->baseurl("/developer/update/start"));
            	}
            }
            catch (AppException $e) 
            {
                
                echo "Error|" . $e->getMessage();
            }
			exit;
		}

		$this->set('newversion',$newVersion);
        $this->set('state',$state);
    }

    public function versionupdateprocessAction($state = NULl, $cmd = '')
    {
        $this->check_admin_login();
		$this->layout = "blank";
		
      	try 
        {	
            $return['state'] = isset($return['state']) ? $return['state'] : "";
          	switch($state)
           	{	
           		case  "complete"	    :          								
           									$return = App::Load("Module/Updatemanager")->complete();           									
           									$this->setNextStep('complete');
                                            throw new AppException($this->__($return['message']));     
            								break; 
           		case  "install"	        :          								
           									$return = App::Load("Module/Updatemanager")->install($cmd);     
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');         									
           									if($return['status'] == 'complete')$this->setNextStep('complete');
           									else $this->setNextStep('install');
           									throw new AppException($this->__($return['message']));     
            								break; 
           		case  "review"	        :          								
           									$return = App::Load("Module/Updatemanager")->review($cmd);  
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');            									
           									if($return['status'] == 'complete')$this->setNextStep('install');
           									else $this->setNextStep('review');
           									throw new AppException($this->__($return['message']));     
            								break; 
                case  "download"	    :          								
           									$return = App::Load("Module/Updatemanager")->download($cmd);
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');   
           									if($return['status'] == 'complete')$this->setNextStep('review');
           									else $this->setNextStep('download');
           									throw new AppException($this->__($return['message']));     
            								break; 
           		case  "createbackup"	:          								
           									$return = App::Load("Module/Updatemanager")->createfilebackup($cmd); 
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');             									
           									if($return['status'] == 'complete')$this->setNextStep('download');
           									else $this->setNextStep('createbackup');
           									throw new AppException($this->__($return['message']));     
            								break;           	
           		case  "preparation"	    :          								
           									$return = App::Load("Module/Updatemanager")->preparation($cmd);
                                            
                                            if($return['state'] == 'Failed')$this->setStatus('Failed');                                            
                                            if($return['status'] == 'complete')$this->setNextStep('createbackup');
           									else $this->setNextStep('preparation');
           									throw new AppException($this->__($return['message']));     
            								break;
           		case  "parsedefinition"	:
            								$this->setNextStep('preparation');
           									App::Load("Module/Updatemanager")->parsedefinition();      
            								break;
           		case  "getdefinition"	:
            								$result = App::Load("Module/Updatemanager")->getdefinition();      
            								break;
            	default					:
                							$result = Array("status"=>"processComplete","message"=>"Repository updates successfully. You may navigate away this page.");
                							break;
           	}
           	
           	
            echo App::Load("Module/Cryptography")->jsonEncode($result);
        }
        catch (AppException $e) 
        {
        	$message = ($this->getStatus()) ? $this->getStatus() : "message";
        	$nextstep = ($this->getNextStep()) ? $this->getNextStep() : "";
        	echo App::Load("Module/Cryptography")->jsonEncode(Array("nextstep"=>$nextstep,"status"=>$message,"message"=>$e->getMessage()));
        }
    }    

    public function clearcacheAction()
    {
        $this->setAdminTab('developer');

        $message = "";
        $cacheAllDef = App::Load("Module/Developer")->setCacheAllDef();

        $def = Array(""=>"All");
        foreach($cacheAllDef as $key => $val )
        {
            $def[$key] = $val['title'];
        }

        if(!empty($this->data))
        {
            App::Load("Module/Developer")->setCacheType($this->data['Cache']["type"])
                                         ->clearCache();
            $message = $this->__("Temporary Cache has been cleared successfully.");
        }

        $spaceEstimate = App::Load("Module/Developer")->cacheSpaceEstimate();

        $this->set('spaceestimate',$spaceEstimate);
        $this->set('message',$message);
        $this->set('cacheAllDef',$def);
    }

    /**
     * Manage Language
     */
    public function languageAction( $lang_file = NULL)
    {
        $this->setAdminTab('developer');

        if( !empty($_POST))
        {   
            $_dom = new DomDocument();
            $_language = $_dom->createElement ('Language');
            $_language = $_dom->appendChild ($_language);
            
            // Base Section
            $_base = $_dom->createElement ('base');
            $_base = $_language->appendChild ($_base);

            $_code = $_dom->createElement ('code');
            $_code->nodeValue = $_POST['data']['code'];
            $_base->appendChild ($_code);

            $_title = $_dom->createElement ('title');
            $_title->nodeValue = $_POST['data']['title'];
            $_base->appendChild ($_title);


            // Language values
            $_langs = $_dom->createElement ('langs');
            $_langs = $_language->appendChild ($_langs);

            foreach($_POST['data']['lang'] as $order => $lang)
            {
                if( $lang['key'] != "" )
                {
                    $_lang = $_dom->createElement ('lang');
                    $_lang = $_langs->appendChild ($_lang);

                    $_key = $_dom->createElement ('key');
                    $_key->nodeValue =$lang['key'];
                    $_key = $_lang->appendChild ($_key);

                    $_val = $_dom->createElement ('val');
                    $_val->nodeValue =$lang['value'];
                    $_key = $_lang->appendChild ($_val);
                }
            }
            
            $_dom->save(LANGUAGE_PATH . "/{$lang_file}");
        }
        
        $lang_fiels = App::Load('Helper/Utility')->getDirLising(LANGUAGE_PATH);
        $this->set('lang_fiels',$lang_fiels['file']);
        
        if(isset($lang_file))
        {
            $lan_xml = simplexml_load_file(LANGUAGE_PATH . "/{$lang_file}");
            $this->set('xml',$lan_xml);
            $this->set('lang_file',$lang_file);            
        }
    }
	


    public function debug_logAction($mode='file', $action = NULL)
    {
        $this->setAdminTab('developer');
        
        if($mode == 'file')
        {
            if( $action == 'clear') App::Helper('Log')->clear('file');
            
            $logData = App::Helper('Log')->readFullLog();
            $this->set('logData',$logData);
        }
        else
        {
            if( $action == 'clear') $this->Log->delete();
            
            $logData = $this->Log->paging(1,50);
            $this->set('logData',$logData);
        }
        
        $this->set('mode',$mode);
    }
}
